﻿using System;
using jQueryApi;
using System.Html;

namespace Quicklight.Web.Razor {

   /// <summary>
   /// This class binds to an attribute of an element. This class simply locates the element identified by the element locator and calls an abstract method Bind
   /// to do the actual binding. Extend this class to bind something to the attribute
   /// </summary>
   public abstract class AttributeBinder : Binder {
      protected string attributeName;

      /// <summary>
      /// Constructs an AttributeBinder that will bind to the specified attribute
      /// </summary>
      /// <param name="attributeName">Attribute to bind to</param>
      public AttributeBinder(string attributeName) {
         this.attributeName = attributeName;
      }

      /// <summary>
      /// Creates and returns an element locator. The element locator is an attribute set equal to a value. The attribute is bind-attributename and the value is the key provided
      /// </summary>
      /// <param name="key">Unique key for this binder instance</param>
      /// <returns>The element locator that will be used by the Bind method to locate the element</returns>
      public override string GetElementLocator(string key) {
         return String.Format(@"bind-{0}=""{1}""", attributeName, key);
      }

      /// <summary>
      /// This method locates the element using the element locator, ensures that it has an id, then calls the abstract Bind method to bind the element. It then removes the element locator
      /// </summary>
      /// <param name="key">Unique key for this binder instance</param>
      public override void Bind(string key) {
         string elementLocator = GetElementLocator(key);
         elementLocator = elementLocator.Replace("(", @"\(").Replace(":", @"\:").Replace("|", @"\|").Replace(@"\", @"\\").Replace(".", @"\.").Replace(")", @"\)");
         jQueryObject jQueryObject = jQuery.Select(String.Format("[{0}]", elementLocator));
         if (jQueryObject == null)
            return;

         string id = jQueryObject.GetAttribute("id");
         if (String.IsNullOrEmpty(id)) {
            id = key;
            jQueryObject.Attribute("id", id);
         }

         Element element = Document.Instance.GetElementById(id);
         Bind(element);

         jQueryObject.RemoveAttr(String.Format("bind-{0}", attributeName));
      }

      /// <summary>
      /// Abstract Bind method that does the actual binding
      /// </summary>
      /// <param name="element">Element to bind to</param>
      protected abstract void Bind(Element element);
   }
}
